﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using System.Threading;

namespace EPiServer.CdnSupport.Test
{
    /// <summary>
    /// Summary description for TestPerformance
    /// </summary>
    [TestClass]
    public class TestPerformance
    {
        ManualResetEvent ev = new ManualResetEvent(false);
        public TestPerformance()
        {
        }

        [TestMethod]
        public void Verify_Performance_Characteristics()
        {
            MicroCache<int> c = new MicroCache<int>(false);
            for (int i = 0; i < 5000; i++)
            {
                c.Add("key" + i.ToString(), i);
            }

            Thread []threads = new Thread[5];
            for (int i = 0; i < 3; i++)
            {
                threads[i] = new Thread(new ParameterizedThreadStart(Runner1));
                threads[i].Start(c);
            }

            for (int i = 3; i < 5; i++)
            {
                threads[i] = new Thread(new ParameterizedThreadStart(Runner2));
                threads[i].Start(c);
            }

            Thread.Sleep(TimeSpan.FromMilliseconds(10));

            Stopwatch watch = new Stopwatch();
            watch.Start();
            ev.Set();

            for (int i = 0; i < 3; i++)
            {
                threads[i].Join();
            }
            
            watch.Stop();
            Assert.IsTrue(c.CacheAdded > 5500);
            Assert.IsTrue(c.CacheBusy > 0);
            Assert.IsTrue(c.CacheMisses > 200);
            Assert.IsTrue(c.CacheHits > 200000);
            Assert.IsTrue(watch.ElapsedMilliseconds < 3000);
        }

        public void Runner1(object testClass)
        {
            MicroCache<int> c = testClass as MicroCache<int>;
            ev.WaitOne();

            bool isBusy;
            for (int x = 0; x < 100; x++)
            {
                for (int i = 0; i < 5000; i++)
                {
                    int val = c.Get("key" + i.ToString(), out isBusy);
                }

                int retVal1 = c.Get("thread" + x.ToString() + "_" + Thread.CurrentThread.ManagedThreadId.ToString(),out isBusy);              
                c.Add("thread" + x.ToString() + "_" + Thread.CurrentThread.ManagedThreadId.ToString(), x);

                int retVal2 = c.Get("runner" + x.ToString(), out isBusy);
                c.Add("runner" + x.ToString(), x);
            }

        }

        public void Runner2(object testClass)
        {
            MicroCache<int> c = testClass as MicroCache<int>;
            ev.WaitOne();

            bool isBusy;
            for (int x = 99; x >= 0; x--)
            {
                for (int i = 4999; i >= 0; i--)
                {
                    int val = c.Get("key" + i.ToString(), out isBusy);
                }
            }
        }
    }
}
